package com.whfc.iot.mach.codec;

import com.whfc.common.util.VersionUtil;
import com.whfc.iot.mach.constant.MsgConst;
import com.whfc.iot.mach.entity.MachGps;
import com.whfc.iot.mach.entity.MachMsg0x09;
import com.whfc.iot.mach.entity.MachWorkState;
import com.whfc.iot.util.ByteUtil;
import com.whfc.iot.util.MsgDataCodecUtil;
import io.netty.buffer.ByteBuf;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/7/17 9:32
 */
public class MachMsgDataCodec0x09 implements MachMsgDataCodec<MachMsg0x09> {

    public static final double GPS_MULTIPLY = 100000 * 60D;

    @Override
    public void decode(ByteBuf buf, MachMsg0x09 msg) {

        //工作状态
        int workState = buf.readUnsignedByte();
        //时间
        Date time = MsgDataCodecUtil.readDateTime(buf);
        MachWorkState machWorkState = new MachWorkState(time, workState);

        //电池电量
        int batteryPower = buf.readByte();
        if (batteryPower < 0) {
            batteryPower = 0;
        }
        if (batteryPower > 100) {
            batteryPower = 100;
        }

        //gps
        int gpsNum = buf.readByte();
        List<MachGps> gpsList = new ArrayList<>(gpsNum);
        for (int i = 0; i < gpsNum; i++) {
            MachGps gps = this.readGps(buf);
            gpsList.add(gps);
        }

        //主机版本号
        int[] masterVerArr = new int[3];
        masterVerArr[0] = buf.readUnsignedByte();
        masterVerArr[1] = buf.readUnsignedByte();
        masterVerArr[2] = buf.readUnsignedByte();
        String masterVer = VersionUtil.getHardwareVersion(masterVerArr);

        msg.setWorkState(machWorkState);
        msg.setBatteryPower(batteryPower);
        msg.setGpsNum(gpsNum);
        msg.setGpsList(gpsList);
        msg.setMasterVerArr(masterVerArr);
        msg.setMasterVer(masterVer);
    }

    @Override
    public void encode(ByteBuf buf, MachMsg0x09 msg) {

        //终端工作状态
        buf.writeByte(msg.getWorkState().getWorkState());

        //时间
        MsgDataCodecUtil.writeDateTime(buf, msg.getWorkState().getTime());

        //电池电量
        buf.writeByte(msg.getBatteryPower());

        //gps
        buf.writeByte(msg.getGpsNum());
        for (MachGps gps : msg.getGpsList()) {
            this.writeGps(buf, gps);
        }

        //主机版本号
        int[] masterVerArr = VersionUtil.parseHardvareVersion(msg.getMasterVer());
        for (int ver : masterVerArr) {
            buf.writeByte(ver);
        }
    }

    /**
     * gps解码
     *
     * @param buf
     * @return
     */
    private MachGps readGps(ByteBuf buf) {
        int gpsFlag = buf.readUnsignedByte();
        String lngFlag = MsgConst.EAST;
        String latFlag = MsgConst.NORTH;
        switch (gpsFlag) {
            case MsgConst.GPS_FLAG_N_E:
                lngFlag = MsgConst.EAST;
                latFlag = MsgConst.NORTH;
                break;
            case MsgConst.GPS_FLAG_N_W:
                lngFlag = MsgConst.WEST;
                latFlag = MsgConst.NORTH;
                break;
            case MsgConst.GPS_FLAG_S_E:
                lngFlag = MsgConst.EAST;
                latFlag = MsgConst.SOUTH;
                break;
            case MsgConst.GPS_FLAG_S_W:
                lngFlag = MsgConst.WEST;
                latFlag = MsgConst.SOUTH;
                break;
        }

        //经度
        int lngD = buf.readUnsignedByte();
        int[] lngMBytes = new int[3];
        lngMBytes[0] = buf.readUnsignedByte();
        lngMBytes[1] = buf.readUnsignedByte();
        lngMBytes[2] = buf.readUnsignedByte();
        int lngM = ByteUtil.low3ByteToInt(lngMBytes);
        double lng = lngD + (double) lngM / GPS_MULTIPLY;

        //纬度
        int latD = buf.readUnsignedByte();
        int[] latMBytes = new int[3];
        latMBytes[0] = buf.readUnsignedByte();
        latMBytes[1] = buf.readUnsignedByte();
        latMBytes[2] = buf.readUnsignedByte();
        int latM = ByteUtil.low3ByteToInt(latMBytes);
        double lat = latD + (double) latM / GPS_MULTIPLY;

        MachGps gps = new MachGps();
        gps.setLngFlag(lngFlag);
        gps.setLatFlag(latFlag);
        gps.setLngWgs84(lng);
        gps.setLatWgs84(lat);
        return gps;
    }

    /**
     * gps编码
     *
     * @param buf
     * @param gps
     */
    private void writeGps(ByteBuf buf, MachGps gps) {
        //GPS标志位(默认北纬/东经)
        int gpsFlag = 0x0F;
        if (MsgConst.NORTH.equals(gps.getLngFlag())) {
            gpsFlag &= 0xF0;
        }
        if (MsgConst.EAST.equals(gps.getLatFlag())) {
            gpsFlag &= 0x00;
        }
        buf.writeByte(gpsFlag);

        //经度
        int lngD = (int) gps.getLngWgs84();
        int lngM = (int) ((gps.getLngWgs84() - lngD) * GPS_MULTIPLY);
        buf.writeByte(lngD);
        buf.writeBytes(ByteUtil.extractLow3Byte(lngM));

        //纬度
        int latD = (int) gps.getLatWgs84();
        int latM = (int) ((gps.getLatWgs84() - latD) * GPS_MULTIPLY);
        buf.writeByte(latD);
        buf.writeBytes(ByteUtil.extractLow3Byte(latM));
    }
}
